import uuid
import json
from typing import List
from fastapi import APIRouter,WebSocket, WebSocketDisconnect, HTTPException
# from fastapi.websockets import WebSocketState
from pydantic import ValidationError
from ..schemas.chat import ChatRequest, ChatResponse, ChatHistoryItem  # 新增导入
from ..services.chat import chat_with_mcp, chat_with_agent, chat_history  # 新增导入chat_history
from ..services.provider import get_chosen_model_config, get_mcp_config
from ..core.common import WebSocketSender
from ..services import DefaultAgentChat
from .dependencies import AppConfigDependency, WsAppConfigDependency 

from ..core.common.logger import get_logger
logger = get_logger(__name__)

router = APIRouter(prefix="/api", tags=["聊天接口"])
@router.websocket("/chat/ws")
async def websocket_chat(websocket: WebSocket, app_config: WsAppConfigDependency):
    await websocket.accept()
    logger.info(f"New connection from {websocket.client}")
    try:
        ws_sender=WebSocketSender(websocket)
        default_agent=DefaultAgentChat(sender=ws_sender)
        _active = True
        while _active:
            # 接收客户端请求
            try:
                data = await websocket.receive_text()
                request = ChatRequest.model_validate_json(data)
                await default_agent.chat(request, app_config=app_config)
            except ValidationError as e:
                await ws_sender.send(f"Validation error: {e.json()}")
                continue
            except json.JSONDecodeError:
                await ws_sender.send("Invalid JSON format")
                continue
            except HTTPException as e:
                await ws_sender.send(f"HTTPExpected error: {str(e)}")
                continue
            except WebSocketDisconnect:
                    # 在聊天过程中断开连接
                    logger.info("Client disconnected during chat processing")
                    _active = False  # 退出循环
            except Exception as e:
                    logger.error(f"Internal server error: {str(e)}")
                    await ws_sender.send(f"Internal server error: {str(e)}")
    except WebSocketDisconnect:
        logger.info(f"Client disconnected: {websocket.client}")
    except Exception as e:
        logger.error(f"Unexpected error in WebSocket connection: {str(e)}")
        try:
            await websocket.close(code=1011, reason=f"{e}")
        except:
            pass
    
# 新增：获取聊天记录的接口
@router.get("/chat/history", response_model=List[ChatHistoryItem])
async def get_chat_history():
    """获取最近的聊天记录（模拟数据）"""
    # 注意：实际项目中应从数据库查询，这里返回内存存储的模拟数据
    return chat_history
    
@router.post("/chat", response_model=ChatResponse, response_model_exclude_none= True)
async def chat_endpoint(
    request: ChatRequest,
    app_config: AppConfigDependency 
):
    # 从配置中获取模型列表
    session_id=request.session_id or str(uuid.uuid4())
    # to-do: 
    # - 1. need to add filter [provider, model] logic, if get invalid value
    chosen_model=get_chosen_model_config(app_config.models, request.provider, request.selected_model)
    if chosen_model is None:
        raise HTTPException(status_code=400, detail="无效的模型选择")
    mcp_config=get_mcp_config(app_config.mcp_servers, request.mcp_server)
    if mcp_config is None:
        raise HTTPException(status_code=400, detail="无效的MCP Server选择")
    # 调用服务层时传递配置
    #response = await chat_with_mcp(request, mcp_config, chosen_model)
    response = await chat_with_agent(request, mcp_config, chosen_model)
    logger.info(f"[{request.provider}/{request.selected_model}]: generate result successful.")
    # response = f"[{request.provider}/{request.selected_model}]: \n {response}"
    
    return ChatResponse(
        session_id=session_id,
        success=True,
        query={
            "question": request.question,
            "model": f"{request.provider}/{request.selected_model}",
            "mcp": request.mcp_server,
        },
        messages=response,
        used_model=request.selected_model
    )
